package com.study.example.study.extension.easyexcel.write;

import com.alibaba.excel.util.ListUtils;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * easyexcel 测试 写数据策略接口 实现
 *
 * @author RenYuLiang
 */
@Log4j2
@Component
public class TestEasyExcelWriteDataHandlerStrategy implements EasyExcelWriteDataStrategy<EasyExcelWriteDataDemoDTO> {


    /**
     * 每页查询 5000
     */
    private static final Integer PAGE_SIZE = 5000;
    /**
     * 查询最大数据 10000L
     */
    private static final Long MAX_COUNT = 200000000L;

    /**
     * 指定写用哪个 class 去写
     *
     * @return Class
     */
    @Override
    public Class<?> getWriteClass() {
        return EasyExcelWriteDataDemoDTO.class;
    }

    /**
     * 分片写入数据
     *
     * @param arg 参数
     * @return EasyExcelWriteDataDTO
     */
    @Override
    public EasyExcelWriteDataDTO<EasyExcelWriteDataDemoDTO> listWriteData(final Object arg) {
        EasyExcelWriteDataDTO<EasyExcelWriteDataDemoDTO> dto = new EasyExcelWriteDataDTO<>();
        dto.setList(Lists.newArrayList());
        // 获取总数量 模拟
        //long totalCount = ThreadLocalRandom.current().nextLong(0L, 1008570L);
        long totalCount = 200000L;
        if (1L > totalCount) {
            return dto;
        }
        // 创建分页实例
        EasyExcelWritePageDTO pageDTO = EasyExcelWritePageUtils.createEasyExcelWritePageDTO(PAGE_SIZE, MAX_COUNT, totalCount);
        if (!pageDTO.getHasData()) {
            return dto;
        }
        // 计算每页最大数量
        long maxPageCount = pageDTO.getTotalCount() > pageDTO.getPageSize() ? pageDTO.getPageSize() : pageDTO.getTotalCount();
        dto.setList(this.allData(pageDTO.getTotalPage(), maxPageCount));
        return dto;
    }

    /**
     * 模拟循环分页查询数据
     *
     * @param totalPage    总页数
     * @param maxPageCount 每页最大数量
     * @return List
     */
    private List<EasyExcelWriteDataDemoDTO> allData(final long totalPage, final long maxPageCount) {
        // 建的时候就开始计时
        Stopwatch stopwatch = Stopwatch.createStarted();
        List<EasyExcelWriteDataDemoDTO> allList = ListUtils.newArrayList();
        List<EasyExcelWriteDataDemoDTO> list;
        // 数据开始下标
        long pageBegin = 0L;
        for (int i = 0; i < totalPage; i++) {
            list = this.data(maxPageCount, pageBegin);
            allList.addAll(list);
            pageBegin = (i + 1) * maxPageCount;
        }
        // 停止计时，然后计算时长.单位为毫秒
        long elapsed = stopwatch.stop().elapsed(TimeUnit.MILLISECONDS);
        log.info("准备数据耗时(毫秒)={}", elapsed);
        System.out.println("准备数据耗时耗时(毫秒)=" + elapsed);
        return allList;
    }

    /**
     * 模拟数据
     *
     * @param pageCount long 每页多少数据
     * @param pageBegin long 每页开始下标
     * @return List
     */
    private List<EasyExcelWriteDataDemoDTO> data(final long pageCount, final long pageBegin) {
        List<EasyExcelWriteDataDemoDTO> list = ListUtils.newArrayList();
        EasyExcelWriteDataDemoDTO dto;
        for (int i = 0; i < pageCount; i++) {
            dto = new EasyExcelWriteDataDemoDTO();
            dto.setString("字符串-下标:" + pageBegin + "-数据行：" + i);
            dto.setDate(new Date());
            dto.setDoubleData(0.56D);
            // 获取总数量 模拟
            int random = ThreadLocalRandom.current().nextInt(1, 4);
            dto.setGender(random);
            dto.setStatus(String.valueOf(random));
            dto.setNullStr(StringUtils.EMPTY);
            list.add(dto);
        }
        return list;
    }


}
